home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 11
/
Cream of the Crop 11-2.iso
/
extra_2
/
flmgmtcl.zip
/
XSTRING.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-02
|
7KB
|
273 lines
// ==========================================================================
// Class Implementation : CXString
// ==========================================================================
// Source file : stringx.cpp
// Source : Periphere NV (R.Mortelmans)
// Creation Date : 2nd November 1995
// Last Modification : 2nd November 1995
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "xstring.h"
#include <ctype.h>
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#define DECIMAL_CHARACTER_STRING_LENGTH 2 // Including 0-termination
/////////////////////////////////////////////////////////////////////////////
// Definition of static members
char pszDecimalDestination[2];
char* pszDecimalDefault = TEXT(",");
// ... The sequential-evaluation operator (comma operator) is used here
char CXString::cDecimalCharacter(
(::GetProfileString(TEXT("Intl"), TEXT("sDecimal"), pszDecimalDefault, pszDecimalDestination, DECIMAL_CHARACTER_STRING_LENGTH),
*pszDecimalDestination));
// Data members -------------------------------------------------------------
// protected:
// private:
// Member functions ---------------------------------------------------------
// public:
CXString::CXString()
{
}
CXString::CXString(const char* psz)
{
*((CString*)this) = psz;
}
CXString::CXString(const CString& sSource)
{
*((CString*)this) = sSource;
}
CXString::CXString(LONG nSource)
{
char pszBuffer[20];
*this = CXString(ltoa(nSource, pszBuffer, 10));
}
CXString::CXString(const CXString& sString)
: CString(sString)
{
}
CXString& CXString::operator=(const CXString& sString)
{
CString::operator=(sString);
return *this;
}
BOOL CXString::operator==(const CXString& s2) const
{
// The =-operator of CString calls strcmp and thus only compares until the first NULL-character
// This function really compares the entire strings
return (GetLength() == s2.GetLength()) &&
(memcmp(m_pchData, s2.m_pchData, GetLength()) == 0);
}
void CXString::LTrim()
{
int nStringIndex = 0;
int nLength = GetLength();
while( (nStringIndex < nLength) && isspace(GetAt(nStringIndex)) )
nStringIndex++;
if (nStringIndex == nLength)
*this = CXString(TEXT(""));
else
*this = Mid(nStringIndex);
}
void CXString::RTrim()
{
int nStringIndex = GetLength() - 1;
while((0 <= nStringIndex) && isspace(GetAt(nStringIndex)) )
nStringIndex--;
*this = Left(nStringIndex + 1);
}
void CXString::XTrim()
{
// Optimisation :
// The output string sOut is initialized by the value of the string
// The real significant characters in sOut are from position 0 till nPosOut - 1
// Characters are thus added by overwriting a character in sOut and incrementing nPosOut by 1.
// Now memory is allocated only once (at initialisation of sOut)
// When you would start with an empty string and would concatenate characters
// then extra memory must be allocated frequently (overhead).
CXString sOut(*this);
int nPosIn = 0;
int nPosOut = 0;
BOOL bSpace = FALSE;
while (nPosIn < GetLength())
{
if (isspace(GetAt(nPosIn)))
if (bSpace)
{
// ... Second white space character encountered
// Skip this character (do not copy)
nPosIn++;
}
else
{
// ... First white space character encountered
// Copy space (all white space characters are replaced by a space)
sOut.SetAt(nPosOut++, ' ');
nPosIn++;
bSpace = TRUE;
}
else
{
// ... Copying a non white space character
sOut.SetAt(nPosOut++, GetAt(nPosIn++));
bSpace = FALSE;
}
}
*this = sOut.Left(nPosOut);
}
int CXString::GetInt() const
{
return atoi(*this);
}
long CXString::GetLongInt() const
{
return atol(*this);
}
BOOL CXString::IsInt()
{
for (int nIndex = 0; nIndex < GetLength(); nIndex++)
if (!isdigit(GetAt(nIndex)))
return FALSE;
return TRUE;
}
BOOL CXString::IsNumber()
{
const char* pc = *this;
BOOL bDigit = FALSE;
// Skip white space characters
while (isspace(*pc))
pc++;
// Skip sign
if ((*pc == '-') || (*pc == '+'))
pc++;
// Skip digits
while (isdigit(*pc))
{
pc++;
bDigit = TRUE;
}
// Skip decimal sign
if (*pc == cDecimalCharacter)
pc++;
if (!bDigit && !isdigit(*pc))
return FALSE;
// Skip digits
while (isdigit(*pc))
pc++;
// Skip exponent sign and rest
if ((*pc == 'E') || (*pc == 'e') || (*pc == 'D') || (*pc == 'd'))
{
pc++;
// Skip sign
if ((*pc == '-') || (*pc == '+'))
pc++;
// Skip digits
if (!isdigit(*pc))
// Exponent sign is not followed by digits
return FALSE;
while (isdigit(*pc))
pc++;
}
// Skip white space characters
while (isspace(*pc))
pc++;
// Pointer should not be behind the end of the string
ASSERT(pc <= (((const char*)*this) + GetLength()));
// Must be at the end of the string by now, otherwise the number is not valid
return (*pc == '\0');
}
void CXString::Format(const char* pszFormat, const char** rgpsz, int nString)
{
// NOTE: will not work for strings > 255 characters
int nTotalLen = lstrlen(pszFormat);
for (int i = 0; i < nString; i++)
{
if (rgpsz[i] != NULL)
nTotalLen += strlen(rgpsz[i]);
}
const char* pchSrc = pszFormat;
char* pchDest = GetBuffer(nTotalLen+1);
while (*pchSrc != '\0')
{
if (pchSrc[0] == '%' && (pchSrc[1] >= '1' && pchSrc[1] <= '9'))
{
i = pchSrc[1] - '1';
pchSrc += 2;
if (i >= nString)
{
TRACE1(TEXT("CXString::Format : Illegal string index requested %d\n"), i);
*pchDest++ = '?';
}
else if (rgpsz[i] != NULL)
{
strcpy(pchDest, rgpsz[i]);
pchDest += strlen(pchDest);
}
}
else
{
*pchDest++ = *pchSrc++;
}
}
ReleaseBuffer((int)((const char*)pchDest - (const char*)this));
// Release will assert if we went too far
}
void CXString::BarToNull()
{
int nLength = GetLength();
LPTSTR pszData = GetBuffer(nLength);
while ((pszData = _tcschr(pszData, '|')) != NULL)
*pszData++ = '\0';
ReleaseBuffer(nLength);
ASSERT(GetLength() == nLength);
}
CXString::~CXString()
{
}
// protected:
// private:
// ==========================================================================